package tool

import (
	"bytes"
	"encoding/binary"
)

type Buffer struct {
	bytes  *bytes.Buffer
	offset int
}

func NewBuffer(data []byte) *Buffer {
	return &Buffer{
		bytes: bytes.NewBuffer(data),
	}
}

func (b *Buffer) Skip(n int) *Buffer {
	b.Next(n)
	return b
}

func (b *Buffer) Next(n int) []byte {
	b.offset += n
	return b.bytes.Next(n)
}

func (b *Buffer) ReadByte() (byte, error) {
	b.offset++
	return b.bytes.ReadByte()
}

func (b *Buffer) Write(p []byte) (n int, err error) {
	return b.bytes.Write(p)
}

func (b *Buffer) ReadUint16() uint16 {
	return binary.BigEndian.Uint16(b.Next(2))
}

func (b *Buffer) ReadInt16() int16 {
	return int16(b.ReadUint16())
}

func (b *Buffer) ReadUint32() uint32 {
	return binary.BigEndian.Uint32(b.Next(4))
}

func (b *Buffer) ReadInt32() int32 {
	return int32(b.ReadUint32())
}

func (b *Buffer) ReadInt32s(n int) []int32 {
	its := make([]int32, n)
	for i := 0; i < n; i++ {
		its[i] = b.ReadInt32()
	}
	return its
}

func (b *Buffer) Offset() int {
	return b.offset
}

func (b *Buffer) Reset(bytes []byte) (int, error) {
	b.offset = 0
	b.bytes.Reset()
	return b.bytes.Write(bytes)
}

func (b *Buffer) SkipPadding() int {
	for b.offset%4 != 0 {
		b.ReadByte()
	}
	return b.offset
}
